#include "common.h"    // 包含公共头文件
#include "chatTask.h"  // 包含聊天任务处理头文件

using namespace std;

// 定义消息互斥锁（用于线程同步）
static pthread_mutex_t _mxMessage;

// 修改：添加互斥锁定义
std::mutex userMapMutex;

// 修改：移除全局数据库连接
// SQLite::Database db("user.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);

// 在线用户映射表：<socket文件描述符, 用户账号>
map<int, int> userMap;

/**
 * @brief 初始化数据库表结构
 */
void initDatabase(SQLite::Database& db)
{
    // 执行数据库建表命令（如果表不存在则创建）
    db.exec("CREATE TABLE IF NOT EXISTS friend (user1 INTEGER NOT NULL, user2 INTEGER NOT NULL, PRIMARY KEY (user1, user2));");
    db.exec("CREATE TABLE IF NOT EXISTS group_table (group_account INTEGER PRIMARY KEY, group_name TEXT, create_time DATETIME, group_master INTEGER);");
    db.exec("CREATE TABLE IF NOT EXISTS user (account INTEGER PRIMARY KEY AUTOINCREMENT, password VARCHAR(32), name VARCHAR(32), signature TEXT, online INT DEFAULT 0 NOT NULL, icon TEXT);");
    db.exec("CREATE TABLE IF NOT EXISTS member (member_id INTEGER, group_account INTEGER, group_nickname TEXT);");
}

/**
 * @brief 主函数 - 聊天服务器入口
 */
int main(int argc, char* argv[])
{
    // 修改：创建主数据库连接用于初始化
    SQLite::Database main_db("user.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
    initDatabase(main_db);
    
    // 设置默认端口号
    int default_port = 8888;
    int optch = 0;
    
    // 解析命令行参数
    while ((optch = getopt(argc, argv, "s:p:")) != -1)
    {
        switch (optch)
        {
        case 'p':  // 端口参数
            default_port = atoi(optarg);  // 将字符串转换为整数
            LOGINFO("port: %s\n", optarg);  // 记录端口信息日志
            break;
        case '?':  // 未知参数
            LOGINFO("Unknown option: %c\n", (char)optopt);  // 记录错误日志
            break;
        default:
            break;
        }
    }
    
    // 初始化互斥锁
    pthread_mutex_init(&_mxMessage, NULL);
    
    // 声明服务器和客户端地址结构
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len;  // 客户端地址长度

    // 声明监听socket和连接socket
    int listen_fd, connect_fd;

    /*(1) 创建监听套接字*/
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);  // 创建TCP socket
    if (listen_fd == -1)
    {
        perror("Socket Error:");  // 输出socket创建错误
        return 0;
    }

    /*(2) 设置服务器地址结构*/
    bzero(&server_addr, sizeof(server_addr));  // 清空地址结构
    server_addr.sin_family = AF_INET;           // IPv4协议
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有网络接口
    server_addr.sin_port = htons(default_port); // 设置端口号

    // 设置socket选项：允许地址立即重用
    int val = 1;
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(listen_fd));  

    /*(3) 绑定套接字到指定端口*/
    if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("Bind error:");  // 输出绑定错误
        return 0;
    }

    /*(4) 开始监听客户端连接请求*/
    if (listen(listen_fd, 4) == -1)  // 设置监听队列长度为4
    {
        perror("Listen error:");  // 输出监听错误
        return 0;
    }
    
    /*(5) 接受客户端连接并创建处理线程*/
    vector<thread> threadPool;  // 线程池，存储所有客户端处理线程
    
    // 主循环：持续接受客户端连接
    for (;;)
    {
        client_len = sizeof(client_addr);  // 设置客户端地址结构长度
        
        // 接受客户端连接（阻塞调用）
        connect_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_len);
        if (connect_fd < 0)
        {
            perror("accept error");  // 输出接受连接错误
            continue;  // 继续接受其他连接
        }
        
        // 修改：设置socket超时
        struct timeval timeout;
        timeout.tv_sec = 30; // 30秒超时
        timeout.tv_usec = 0;
        setsockopt(connect_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
        setsockopt(connect_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
        
        // 记录客户端连接信息
        LOGINFO("Connect from %s:%u...\n", 
                inet_ntoa(client_addr.sin_addr),     // 客户端IP地址
                ntohs(client_addr.sin_port));        // 客户端端口号
        
        // 修改：添加锁保护userMap访问
        {
            std::lock_guard<std::mutex> lock(userMapMutex);
            userMap[connect_fd] = connect_fd;  // 初始映射
        }
        
        // 创建新线程处理客户端连接
        threadPool.emplace_back(taskThread, connect_fd);
    }
    
    // 关闭监听socket
    close(listen_fd);
    
    return 0;  // 程序正常退出
}